home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / c / run_process.c < prev    next >
C/C++ Source or Header  |  1992-01-22  |  7KB  |  306 lines

  1. /* By Mike Ballantyne */
  2.  
  3.  
  4. #include "include.h"
  5. #ifdef RUN_PROCESS
  6.  
  7. /*
  8.  * System Include Files
  9.  *
  10.  * The system files here each define some part of the information needed to
  11.  * compile the inet package.  They need to exist of every host you port this
  12.  * code to.  I have added some comments that I hope will help you "find"
  13.  * the file if it does not have the same name of your host.
  14.  */
  15. #include <errno.h>    /* errno global, error codes for UNIX IO    */
  16. #include <sys/types.h>    /* Data types definitions            */
  17. #include <sys/socket.h>    /* Socket definitions with out this forget it    */
  18. #include <netinet/in.h>    /* Internet address definition AF_INET etc...    */
  19. #include <signal.h>    /* UNIX Signal codes                */
  20. #include <sys/ioctl.h>    /* IO control standard UNIx fair        */
  21. #include <sys/file.h>
  22. #include <fcntl.h>    /* Function to set socket aync/interrupt    */
  23. #include <sys/time.h>    /* Time for select time out                     */
  24. #include <netdb.h>    /* Data Base interface for network files    */
  25. #include <stdio.h>
  26.  
  27. /* LISP - Lisp Wrapper for the "c" code.
  28.  *
  29.  * The lisp OBJECT is passed to the code and a string must be extracted
  30.  * and null terminated to make it work with the "C" code.
  31.  *
  32.  * Lisp Interface code.
  33.  */
  34.  
  35. static char *lisp_to_string(string)
  36. object string;
  37. {
  38.     int    i, len;
  39.     char    *sself;
  40.     char    *cstr;
  41.  
  42.     len = string->st.st_fillp;
  43.  
  44.     cstr = (char *) malloc (len+1);
  45.     sself = &(string->st.st_self[0]);
  46.     for (i=0; i<len; i++)
  47.     {
  48.         cstr[i] = sself[i];
  49.     }
  50.     cstr[i] = 0;
  51.     return (cstr);
  52. }
  53.  
  54. /* open - Open a socket to a server that you know by port number.
  55.  *
  56.  * The caller must know the number of the service and and name of the
  57.  * host that tyhe serive is on.  The name of the host can be "localhost"
  58.  * for a service on the same host as the clinet.
  59.  *
  60.  */
  61. static int open(host,server)
  62. char    *host;
  63. int    server;
  64. {
  65.     int res;
  66.     int pid;
  67.     int    sock;
  68.     struct    hostent    *hp;
  69.     struct    sockaddr_in    sock_add;    /* Address of socket          */
  70.  
  71.     if((hp = gethostbyname(host)) == NULL)
  72.     {
  73.         FEerror("No such host.");
  74.     }
  75.  
  76.     bzero((char *)&sock_add, sizeof(sock_add));
  77.     bcopy(hp->h_addr, (char *)&sock_add.sin_addr, hp->h_length);
  78.     sock_add.sin_family = hp->h_addrtype;
  79.     sock_add.sin_port = server;
  80.  
  81.     sock = socket( hp->h_addrtype, SOCK_STREAM , 0);
  82.  
  83.     if(sock < 1)
  84.     {
  85.         FEerror("No Sockets!");
  86.     }
  87.  
  88.     if(connect(sock, (char *)&sock_add, sizeof(sock_add)) < 0)
  89.     {
  90.         close(sock);
  91.         FEerror("Connection Failed.");
  92.     }
  93.     pid = getpid();
  94.     if(ioctl(sock, SIOCSPGRP, (char *)&pid) < 0 )
  95.     {
  96.         FEerror("Could not set process group of socket.");
  97.     }
  98.  
  99. #ifdef OVM_IO
  100.     res = fcntl(sock,F_SETFL,FASYNC | FNDELAY);
  101. #else
  102.     res = fcntl(sock,F_SETFL,FASYNC);
  103. #endif
  104.     return(sock);
  105. }
  106. #define SETBUF(stream) \
  107.     stream->sm.sm_buffer = alloc_contblock(BUFSIZ); \
  108.     setbuf(stream->sm.sm_fp,stream->sm.sm_buffer)
  109.  
  110. object make_stream(host_l,socket,smm)
  111. object    host_l;
  112. int socket;
  113. enum smmode smm;
  114. {
  115.     char    *mode;
  116.     object    stream;
  117.     FILE    *fp;
  118.     vs_mark;
  119.  
  120.  
  121.     switch(smm)
  122.     {
  123.     case smm_input:
  124.         mode = "r";
  125.         break;
  126.     case smm_output:
  127.         mode = "w";
  128.         break;
  129.     default:
  130.         FEerror("make_stream : wrong mode");
  131.     }
  132.  
  133.     fp = fdopen(socket,mode);
  134.     stream = (object)  alloc_object(t_stream);
  135.     stream->sm.sm_mode = (short)smm;
  136.     stream->sm.sm_fp = fp;
  137.     fp->_base = BASEFF;
  138.     stream->sm.sm_object0 = Sstring_char;
  139.     stream->sm.sm_object1 = host_l;
  140.     stream->sm.sm_int0 = stream->sm.sm_int1 = 0;
  141.     vs_push(stream);
  142.     SETBUF(stream)  ;
  143.     vs_reset;
  144.     return(stream);
  145. }
  146.  
  147. object make_socket_stream(host_l,port)
  148. object    host_l;
  149. object    port;
  150. {
  151.     char    *host = lisp_to_string(host_l);
  152.     object    stream_in;
  153.     object    stream_out;
  154.     object    stream;
  155.     int    socket;
  156.  
  157.     socket = open(host, fix(port));
  158.        stream_in  = make_stream(host_l,socket, smm_input);
  159.        stream_out = make_stream(host_l,socket, smm_output);
  160.  
  161.     stream = make_two_way_stream(stream_in,stream_out);
  162.  
  163.     return(stream);
  164. }
  165.  
  166. void
  167. siLmake_socket_stream()
  168. {
  169.   check_arg(2);
  170.   vs_base[0] = make_socket_stream(vs_base[0], vs_base[1]);
  171.   vs_pop;
  172. }
  173.  
  174. /*
  175.  * make 2 two-way streams
  176.  */
  177.  
  178. object
  179. make_socket_pair()
  180. {
  181.   int sockets_in[2];
  182.   int sockets_out[2];
  183.   FILE *fp1, *fp2;
  184.   int pid;
  185.   object stream_in, stream_out, stream;
  186.  
  187.   if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets_in) < 0)
  188.     FEerror("Failure to open socket stream pair", 0);
  189.   if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockets_out) < 0)
  190.     FEerror("Failure to open socket stream pair", 0);
  191.   fp1 = fdopen(sockets_in[0], "r");
  192.   fp2 = fdopen(sockets_out[0], "w");
  193.  
  194. #ifdef OVM_IO
  195.   pid = getpid();
  196.   ioctl(sockets_in[0], SIOCSPGRP, (char *)&pid);
  197.   if( fcntl(sockets_in[0], F_SETFL, FASYNC | FNDELAY) == -1)
  198.     perror("Couldn't control socket");
  199.  
  200. #endif
  201.  
  202.   fp2->_base = BASEFF;
  203.   fp1->_base = BASEFF;
  204.   stream_in = (object) alloc_object(t_stream);
  205.   stream_in->sm.sm_mode = smm_input;
  206.   stream_in->sm.sm_fp = fp1;
  207.   stream_in->sm.sm_int0 = sockets_in[1];
  208.   stream_in->sm.sm_int1 = 0;
  209.   stream_out = (object) alloc_object(t_stream);
  210.   stream_out->sm.sm_mode = smm_output;
  211.   stream_out->sm.sm_fp = fp2;
  212.   SETBUF(stream_in);
  213.   SETBUF(stream_out);
  214.   stream_out->sm.sm_int0 = sockets_out[1];
  215.   stream_out->sm.sm_int1 = 0;
  216.   stream = make_two_way_stream(stream_in, stream_out);
  217.   return(stream);
  218. }
  219. /* the routines for spawning off a process with streams 
  220.  *
  221.  * Assumes that istream and ostream are both associated
  222.  * with "C" type streams.
  223.  */
  224.  
  225.  
  226. spawn_process_with_streams(istream, ostream, pname, argv)
  227. object istream;
  228. object ostream;
  229. char *pname;
  230. char **argv;
  231. {
  232.  
  233.   int fdin;
  234.   int fdout;
  235.   if (istream->sm.sm_fp == NULL || ostream->sm.sm_fp == NULL)
  236.     FEerror("Cannot spawn process with given stream", 0);
  237.   fdin = istream->sm.sm_int0;
  238.   fdout = ostream->sm.sm_int0;
  239.   if (fork() == 0)
  240.     { /* the child --- replace standard in and out with descriptors given */
  241.       close(0);
  242.       dup(fdin);
  243.       close(1);
  244.       dup(fdout);
  245.       fprintf(stderr, "\n***** Spawning process %s ", pname);
  246.       if (execvp(pname, argv) == -1)
  247.     {
  248.       fprintf(stderr, "\n***** Error in process spawning *******");
  249.       fflush(stderr);
  250.       exit(1);
  251.     }
  252.     }
  253.  
  254.  
  255.  
  256.   
  257. }
  258.     
  259.       
  260. run_process(filename, argv)
  261. char *filename;
  262. char **argv;
  263. {
  264.   object stream = make_socket_pair();
  265.   spawn_process_with_streams(stream->sm.sm_object1,
  266.                 stream->sm.sm_object0,
  267.                 filename, argv);
  268.   vs_base[0] = stream;
  269.   vs_base[1] = Cnil;
  270.   vs_top = vs_base + 2;
  271. }
  272.     
  273. siLrun_process()
  274. {
  275.   int i;
  276.   object arglist;
  277.   char *argv[100];
  278.  
  279.   arglist = vs_base[1];
  280.   argv[0] = "";
  281.   for(i = 1; arglist != Cnil; i++) {
  282.      argv[i] = lisp_to_string(arglist->c.c_car);
  283.      arglist = arglist->c.c_cdr;
  284.   }
  285.   argv[i] = (char *)0;
  286.   run_process(object_to_string(vs_base[0]), argv);
  287. }
  288.  
  289. siLmake_socket_pair()
  290. {
  291.   make_socket_pair();
  292. }
  293.  
  294. init_socket_function()
  295. {
  296.   make_si_function("MAKE-SOCKET-STREAM", siLmake_socket_stream); 
  297.   make_si_function("MAKE-SOCKET-PAIR", siLmake_socket_pair);
  298.   make_si_function("RUN-PROCESS", siLrun_process);
  299. }
  300.  
  301. #else /* no RUN_PROCESS */
  302.  
  303. init_socket_function(){;}
  304.  
  305. #endif     
  306.